package com.wzh.glsc.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.wzh.common.utils.R;
import com.wzh.glsc.cart.config.CartInterceptor;
import com.wzh.glsc.cart.feign.SkuServiceFeign;
import com.wzh.glsc.cart.service.CartService;
import com.wzh.glsc.cart.to.UserInfoTo;
import com.wzh.glsc.cart.vo.CartItemVo;
import com.wzh.glsc.cart.vo.CartVo;
import com.wzh.glsc.cart.vo.SkuInfoVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;


/**
 * @author xiaoming
 * @PackageName:com.wzh.glsc.cart.service.impl
 * @ClassName:@{NAME}
 * @Description:
 * @date:@{DATE}@{TIME}
 */
@Service("cartService")
public class CartServiceImpl implements CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SkuServiceFeign skuServiceFeign;
    @Resource
    private ThreadPoolExecutor executor;

    private static final String CART_PREFIX="gulimall:cart:";

//    @SneakyThrows
    @Override
    public CartItemVo addCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        CartItemVo cartItemVo;
        //获取 购物车
        BoundHashOperations<String, Object, Object> hashOps = getCart();
        //取出购物车的该商品
        String res = (String) hashOps.get(skuId.toString());
        if(StringUtils.isEmpty(res)){
            //如果没有就添加该商品
            cartItemVo=querySkuInfoAddCartItem(skuId, num);
        }else {
            //有就数量+
            cartItemVo = JSON.parseObject(res, CartItemVo.class);
            cartItemVo.setCount(cartItemVo.getCount()+num);
            cartItemVo.setTotalPrice(cartItemVo.getTotalPrice());
        }
        //放入redis中
        //将商品放入hashMap中，key为拿到时绑定的userKey
        //  值为skuId:{"cartItemVo":"cartItemVo",}
        hashOps.put(skuId.toString(),JSON.toJSONString(cartItemVo));
        return cartItemVo;
    }

    @Override
    public CartItemVo queryCartItemBySkuId(Long skuId) {
        //这里获取到当前的用户的购物车
        BoundHashOperations<String, Object, Object> cart = getCart();
        //取出商品信息
        String  res = (String) cart.get(skuId.toString());
        return JSONObject.parseObject(res, CartItemVo.class);
    }

    @Override
    public CartVo getCartList() throws ExecutionException, InterruptedException {
        CartVo cartVo = new CartVo();
        UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
        //取出临时登录的购物车数据
        cartVo.setItems(getCartListByKey(CART_PREFIX+userInfoTo.getUserKey()));
        //已登录
        if(userInfoTo.getUserId()!=null){
            //临时购物车有数据就合并用户的购物中
            if(cartVo.getCountNum()!=0){
                for(CartItemVo cartItemVo : cartVo.getItems()){
                    addCart(cartItemVo.getSkuId(),cartItemVo.getCount());
                }
                clearCart(CART_PREFIX+userInfoTo.getUserKey());
            }
            cartVo.setItems(getCartListByKey(CART_PREFIX+userInfoTo.getUserId()));
        }
        return cartVo;
    }

    @Override
    public void clearCart(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public void countItem(Long skuId, Integer num) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        //取出商品信息
        String  res = (String) cart.get(skuId.toString());
        CartItemVo cartItemVo = JSONObject.parseObject(res, CartItemVo.class);
        cartItemVo.setCount(num);
        cart.put(skuId.toString(),JSON.toJSONString(cartItemVo));
    }

    @Override
    public void deleteItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        cart.delete(skuId.toString());
    }

    @Override
    public void checkItem(Long skuId, Integer checked) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        //取出商品信息
        String  res = (String) cart.get(skuId.toString());
        CartItemVo cartItemVo = JSONObject.parseObject(res, CartItemVo.class);
        cartItemVo.setCheck(checked==1? true : false);
        cart.put(skuId.toString(),JSON.toJSONString(cartItemVo));
    }

    @Override
    public List<CartItemVo> checkedItem() {
        UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
        if(userInfoTo.getUserId()==null){
            return null;
        }
        List<CartItemVo> cartListByKey = getCartListByKey(CART_PREFIX + userInfoTo.getUserId());
        return cartListByKey.stream().filter(obj->obj.getCheck()).collect(Collectors.toList());
    }

    public List<CartItemVo> getCartListByKey(String key){
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(key);
        List<Object> values = boundHashOps.values();
        if(values!=null&&values.size()!=0){
            List<CartItemVo> collect = values.stream().map((obj) -> {
                String str = (String) obj;
                return JSON.parseObject(str, CartItemVo.class);
            }).collect(Collectors.toList());
            return collect;
        }
        return null;
    }

    /**
     * 查出sku信息并封装成CartItemVo对象
     */
    public CartItemVo querySkuInfoAddCartItem(Long skuId, Integer num) throws InterruptedException, ExecutionException {
        CartItemVo cartItemVo = new CartItemVo();
        //使用多线程异步读取购物车
        //远程获取商品属性,并添加到CartItemVo中
        CompletableFuture<Void> skuInfoVoFuture = CompletableFuture.runAsync(() -> {
            R skuInfoR = skuServiceFeign.info(skuId);
            SkuInfoVo skuInfo = skuInfoR.getData("skuInfo",new TypeReference<SkuInfoVo>() {
            });
            cartItemVo.setTitle(skuInfo.getSkuTitle());
            cartItemVo.setPrice(skuInfo.getPrice());
            cartItemVo.setImage(skuInfo.getSkuDefaultImg());
            cartItemVo.setSkuId(skuId);
            cartItemVo.setCheck(true);
            cartItemVo.setCount(num);
        }, executor);

        //远程获取套餐属性，并添加到CartItemVo中
        CompletableFuture<Void> skuAttrValuesFuture = CompletableFuture.runAsync(() -> {
            R skuAttrValuesStr = skuServiceFeign.getSkuAttrValuesAsStringListBySkuId(skuId);
            List<String> skuAttrValues = skuAttrValuesStr.getData(new TypeReference<List<String>>() {
            });
            cartItemVo.setSkuAttrValues(skuAttrValues);
        }, executor);

        CompletableFuture.allOf(skuInfoVoFuture,skuAttrValuesFuture).get();
        cartItemVo.setTotalPrice(cartItemVo.getTotalPrice());
        return cartItemVo;
    }

    /**
     * 获取到查询的购物车
     * @return
     */
    public BoundHashOperations<String, Object, Object> getCart() {
        //判断登录状态
        UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
        String userKey="";
        if(userInfoTo.getUserId()!=null){
            userKey=CART_PREFIX+userInfoTo.getUserId();
        }else {
            userKey=CART_PREFIX+userInfoTo.getUserKey();
        }
        //绑定操作的hash key
       return redisTemplate.boundHashOps(userKey);
    }
}
